﻿using Factory;
using Hero;
using Services.Progress;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;

namespace UI
{
    public class Hud : MonoBehaviour
    {
        private IGameFactory _gameFactory;
        private IProgressService _progressService;
        [SerializeField] private Transform _livesHolder;
        [SerializeField] private Transform _ammoHolder;
        [SerializeField] private TextMeshProUGUI _score;
        private List<GameObject> _livesList = new();
        private List<GameObject> _ammoList = new();
        private HeroHealth _heroHealth;
        private HeroShoot _heroShoot;
        private HeroReload _heroReload;
        private HeroScore _heroScore;

        public void Construct(IGameFactory gameFactory, IProgressService progressService, HeroHealth heroHealth, HeroShoot heroShoot, HeroReload heroReload, HeroScore heroScore)
        {
            _gameFactory = gameFactory;
            _progressService = progressService;
            _heroHealth = heroHealth;
            _heroHealth.HealthIncreased += OnHealthGain;
            _heroHealth.HealthDecreased += OnHealthLoss;
            _heroShoot = heroShoot;
            _heroShoot.Shot += RemoveBullet;
            _heroReload = heroReload;
            _heroReload.Reloaded += OnReload;
            _heroScore = heroScore;
            _heroScore.Updated += SetScore;
        }

        private void OnDestroy()
        {
            _heroHealth.HealthIncreased -= OnHealthGain;
            _heroHealth.HealthDecreased -= OnHealthLoss;
            _heroShoot.Shot -= RemoveBullet;
            _heroReload.Reloaded -= OnReload;
            _heroScore.Updated -= SetScore;
        }

        public (Transform Lives, Transform Ammo) GetHolders() => 
            (_livesHolder, _ammoHolder);

        public void SetScore() =>
            _score.text = $"{_progressService.Progress.HeroState.CurrentScore}";

        public void InitLivesList(List<GameObject> livesList) => 
            _livesList = livesList;

        public void InitAmmoList(List<GameObject> ammoList) => 
            _ammoList = ammoList;

        private void OnHealthGain() =>
            _livesList.Add(_gameFactory.CreateHudLife(_livesHolder));

        private void OnHealthLoss()
        {
            var life = _livesList.First();
            _livesList.Remove(life);
            Destroy(life);
        }

        private void OnReload()
        {
            foreach (var ammo in _ammoList) 
                Destroy(ammo);
            _ammoList.Clear();
            for (var i = 0; i < _progressService.Progress.HeroState.CurrentAmmo; i++)
                AddBullet();
        }

        private void AddBullet() =>
            _ammoList.Add(_gameFactory.CreateHudAmmo(_ammoHolder));

        private void RemoveBullet()
        {
            var bullet = _ammoList.First();
            _ammoList.Remove(bullet);
            Destroy(bullet);
        }
    }
}